﻿using gt.rediscachemanager.Entry;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace gt.rediscachemanager
{
    public interface IRedisClientAsync
    {
        #region Key

        /// <summary>
        /// Key是否存在
        /// </summary>
        Task<bool> KeyExistsAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 删除Key
        /// </summary>
        Task<bool> KeyRemoveAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 设置key过期时间
        /// </summary>
        Task<bool> KeyExpiredAsync(string key, TimeSpan expiredTime, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 查看key的过期时间
        /// </summary>
        Task<TimeSpan?> KeyTimeToLiveAsync(string key, CommandFlags flags = CommandFlags.None);

        #endregion

        #region String

        /// <summary>
        /// 设置string key-value
        /// </summary>
        Task<bool> StringSetAsync(string key, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None, When when = When.Always);
        /// <summary>
        /// append string
        /// 返回 append后 string length
        /// </summary>
        Task<long> StringAppendAsync(string key, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 设置string key-value,并返回旧值
        /// </summary>
        /// <returns></returns>
        Task<string> StringGetSetAsync(string key, string value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取string key-value
        /// </summary>
        Task<string> StringGetAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 原子性key-value 值增长
        /// </summary>
        Task<long> StringIncrementAsync(string key, TimeSpan? expiredTime = null, long inc = 1, CommandFlags flags = CommandFlags.None);

        #endregion

        #region Hash

        /// <summary>
        /// 设置hash key field value
        /// </summary>
        Task<bool> HashSetAsync(string key, string field, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None, When when = When.Always);
        /// <summary>
        /// 设置hash key 批量field value
        /// 注：如果values很大，请分批Set
        /// </summary>
        Task<bool> HashSetAsync(string key, Dictionary<string, string> values, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取hash所有 field-value 值
        /// 注：如果hash内数据量很大，请使用 hashscan 方法
        /// </summary>
        Task<Dictionary<string, string>> HashGetAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取hash key field-value值
        /// </summary>
        Task<string> HashGetAsync(string key, string field, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// Hash field是否存在
        /// </summary>
        Task<bool> HashExistsAsync(string key, string field, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 删除hash key field-value值
        /// </summary>
        Task<bool> HashRemoveAsync(string key, string field, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 批量删除hash key field-value值
        /// 注：如果fields很大，请分批删除
        /// </summary>
        Task<long> HashRemoveAsync(string key, string[] fields, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 原子性 hash value 增长
        /// </summary>
        Task<long> HashIncrementAsync(string key, string field, TimeSpan? expiredTime = null, long inc = 1, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取hash所有的field
        /// 注：如果hash内数据量很大，请使用 hashscan 方法
        /// </summary>
        Task<string[]> HashFieldsAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取hash所有的value
        /// 注：如果hash内数据量很大，请使用 hashscan 方法
        /// </summary>
        Task<string[]> HashValuesAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取hash长度
        /// </summary>
        Task<long> HashLengthAsync(string key, CommandFlags flags = CommandFlags.None);

        #endregion

        #region List

        /// <summary>
        /// index 获取value
        /// </summary>
        Task<string> ListGetAsync(string key, int index, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 在另一个value右边，插入list value,
        /// </summary>
        Task<long> ListInsertAfterAsync(string key, string pivot, string insertValue, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 在另一个value左边，插入list value,
        /// </summary>
        Task<long> ListInsertBeforeAsync(string key, string pivot, string insertValue, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 返回左边头一个key-value并删除
        /// </summary>
        Task<string> ListLeftPopAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 从左边插入一个key-value
        /// 返回long length
        /// </summary>
        Task<long> ListLeftPushAsync(string key, string value, When when = When.Always, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// list长度
        /// </summary>
        Task<long> ListLengthAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取某一段list key-value
        /// 从 startIndex 到 endIndexAsync(包括endIndex)
        /// </summary>
        Task<string[]> ListRangeAsync(string key, long startIndex, long endIndex, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 返回右边头一个key-value并删除
        /// </summary>
        Task<string> ListRightPopAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 从右边插入一个key-value
        /// 返回long length
        /// </summary>
        Task<long> ListRightPushAsync(string key, string value, When when = When.Always, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 按序号插入value,序号不能超过队列长度
        /// </summary>
        Task ListSetByIndexAsync(string key, long index, string value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 保留队列一段数据
        /// </summary>
        Task ListTrimAsync(string key, long start, long stop, CommandFlags flags = CommandFlags.None);

        #endregion

        #region Set

        /// <summary>
        /// 插入一个value,若set中不存在，返回true.若存在，则忽略，返回false
        /// </summary>
        Task<bool> SetAddAsync(string key, string value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 插入多个value，返回插入的个数，不包括已经存在的value
        /// </summary>
        Task<long> SetAddAsync(string key, string[] values, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合 交/并/差 集,返回结果集
        /// 集群模式不支持
        /// </summary>
        Task<string[]> SetCombineAsync(SetOperation operation, string[] keys, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合 交/并/差 集，返回结果集
        /// 集群模式不支持
        /// </summary>
        Task<string[]> SetCombineAsync(SetOperation operation, string first, string second, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合 交/并/差 集,并存入另一个集合中，返回结果集长度
        /// 集群模式不支持
        /// </summary>
        Task<long> SetCombineAndStoreAsync(SetOperation operation, string destination, string[] keys, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合 交/并/差 集,并存入另一个集合中，返回结果集长度
        /// 集群模式不支持
        /// </summary>
        Task<long> SetCombineAndStoreAsync(SetOperation operation, string destination, string first, string second, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合是否包含某成员
        /// </summary>
        Task<bool> SetContainsAsync(string key, string value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合长度
        /// </summary>
        Task<long> SetLengthAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合所有成员
        /// </summary>
        Task<string[]> SetMembersAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 转移集合某个成员至另外一个集合，成功返回true,若value不是source一员你，返回false
        /// 集群模式不支持
        /// </summary>
        Task<bool> SetMoveAsync(string source, string destination, string value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 删除并随机获得一个集合成员
        /// </summary>
        Task<string> SetPopAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 返回一个随机成员
        /// </summary>
        Task<string> SetRandomMemberAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 返回一定数量的集合成员
        /// </summary>
        Task<string[]> SetRandomMembersAsync(string key, long count, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 删除一批集合成员，返回实际删除的数量
        /// </summary>
        Task<long> SetRemoveAsync(string key, string[] values, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 删除集合成员，成功删除返回true
        /// </summary>
        Task<bool> SetRemoveAsync(string key, string value, CommandFlags flags = CommandFlags.None);

        #endregion

        #region SortSet

        /// <summary>
        /// 新增集合数据
        /// True if the value was added, False if it already existed (the score is still updated)
        /// </summary>
        Task<bool> SortedSetAddAsync(string key, string member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合数据score -value
        /// </summary>
        Task<double> SortedSetDecrementAsync(string key, string member, double value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合数据score +value
        /// </summary>
        Task<double> SortedSetIncrementAsync(string key, string member, double value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合分数段长度，默认全长，且包括起始段
        /// </summary>
        /// <returns></returns>
        Task<long> SortedSetLengthAsync(string key, double min = -1.0 / 0.0, double max = 1.0 / 0.0, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合分数段内的数据，默认全长，且包括起始段
        /// </summary>
        Task<string[]> SortedSetRangeByRankAsync(string key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 集合分数段内的数数据，默认全长，且包括起始段
        /// </summary>
        /// <param name="key"></param>
        Task<string[]> SortedSetRangeByScoreAsync(string key, double start = -1.0 / 0.0, double stop = 1.0 / 0.0, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 删除集合成员
        /// </summary>
        Task<bool> SortedSetRemoveAsync(string key, string member, CommandFlags flags = CommandFlags.None);

        #endregion

        #region HyperLogLog

        /// <summary>
        /// 新增一个值，估值变化
        /// </summary>
        Task<bool> HyperLogLogAddAsync(string key, string value, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 新增多个值，估值变化
        /// </summary>
        Task<bool> HyperLogLogAddAsync(string key, string[] values, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取HyperLogLog的近似基数
        /// </summary>
        Task<long> HyperLogLogLengthAsync(string key, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取多个HyperLogLog的近似基数的并集
        /// </summary>
        Task<long> HyperLogLogLengthAsync(string[] keys, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 多个HyperLogLog合并到一个新的HyperLogLog结构中
        /// </summary>
        Task HyperLogLogMergeAsync(string destination, string[] sourceKeys, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 多个HyperLogLog合并到一个新的HyperLogLog结构中
        /// </summary>
        Task HyperLogLogMergeAsync(string destination, string first, string second, CommandFlags flags = CommandFlags.None);

        #endregion

        #region Bitmaps

        /// <summary>
        /// 获取Bit统计数据
        /// </summary>
        Task<long> StringBitCountAsync(string key, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 多个Bit数据ADD/OR/XOR/NOT操作，并将结果存到一个新的Bit数据中
        /// </summary>
        Task<long> StringBitOperationAsync(Bitwise operation, string destination, string[] keys, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 多个Bit数据ADD/OR/XOR/NOT操作，并将结果存到一个新的Bit数据中
        /// </summary>
        Task<long> StringBitOperationAsync(Bitwise operation, string destination, string first, string second = null, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取第一个符合Bit的Position
        /// </summary>
        Task<long> StringBitPositionAsync(string key, bool bit, long start = 0, long end = -1, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 获取Bit Position值
        /// </summary>
        Task<bool> StringGetBitAsync(string key, long offset, CommandFlags flags = CommandFlags.None);
        /// <summary>
        /// 设置Bit Position值
        /// </summary>
        Task<bool> StringSetBitAsync(string key, long offset, bool bit, CommandFlags flags = CommandFlags.None);

        #endregion
    }
}
